package com.wwdx.controller.base;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.wwdx.BaseCommons;
import com.wwdx.model.dto.ResultBean;
import com.wwdx.utils.ConstantHolder;
import com.wwdx.utils.Md5Util;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import java.util.SortedMap;
import java.util.regex.Pattern;

/**
 * 基础控制器
 * @author liguoliang
 * @date 2017-11-13
 */
public abstract class BaseController extends BaseCommons {

    /**
     * 验证签名参数是否为空
     */
    protected SortedMap<String, Object> getSortedMap(String token,String timestamp){
        Preconditions.checkArgument(StringUtils.isNotBlank(token),"token is null");
        Preconditions.checkArgument(StringUtils.isNotBlank(timestamp),"timestamp is null");
        SortedMap<String, Object> sortedMap = Maps.newTreeMap();
        sortedMap.put("token", token);
        sortedMap.put("timestamp", timestamp);
        return sortedMap;
    }

    /**
     * 验证签名是否正确
     */
	protected ResultBean validSignResult(String sign, SortedMap<String, Object> sortedMap){
        String timestamp = sortedMap.get("timestamp").toString(),reg = "\\d{13}",msg;
        boolean matches = Pattern.compile(reg).matcher(timestamp).matches();
        if (!matches){
            msg = "timestamp format is error";
            return this.renderError(msg);
        }
        long seconds = (System.currentTimeMillis() - Long.valueOf(timestamp)) / 1000;
        //超过180秒失效
        int i = 180;
        if (seconds < i){
            if (!this.createSign(sortedMap).equalsIgnoreCase(sign)) {
                msg = "签名失败";
                return this.renderError(msg);
            }
            return this.renderSuccess();
        }
        msg = "timestamp is expire";
        return this.renderError(msg);
    }

    /**
     * MD5加密
     * @param sortedMap 签名参数
     * @return 签名
     */
    private String createSign(SortedMap<String, Object> sortedMap) {
        StringBuilder sb = new StringBuilder();
        sortedMap.forEach((k,v)-> sb.append(k).append(v));
        sb.append(ConstantHolder.Constant.API_RULES);
        return Md5Util.encodeByMD5(sb.toString()).toUpperCase();
    }

    /**
     * 验证用户是否登录
     */
    protected ResultBean validSignTokenResult(String sign, SortedMap<String, Object> sortedMap){
        ResultBean resultBean = this.validSignResult(sign,sortedMap);
        int status = resultBean.getStatus();
        if (status == 0){
            String openId = wwdxWeixinUserService.getByToken(sortedMap.get("token").toString());
            if (openId == null){
                String msg = "用户账号异常,为了您的账号安全.请重新登录";
                return this.renderError(msg);
            }
            resultBean.setData(openId);
        }
        return resultBean;
    }

    /**
     * redis分页
     */
    protected BaseController.Page getRedisPages(int page, int rows){
        if (page > 1){
            page = (page-1) * rows;
            rows = page + rows;
        }else {
            page = 0;
            rows = rows -1;
        }
        return new BaseController.Page(page,rows);
    }

    @Setter
    @Getter
    @AllArgsConstructor
    protected class Page{
        private int page;
        private int rows;
    }

	/**
	 * 渲染失败数据（带消息）
	 * @param msg 需要返回的消息
	 * @return result
	 */
	protected ResultBean renderError(String msg) {
		return new ResultBean(ResultBean.FAIL,msg);
	}

	/**
	 * 渲染成功数据
	 * @return result
	 */
	protected ResultBean renderSuccess() {
		return new ResultBean();
	}

	/**
	 * 渲染成功数据（带数据）
	 * @param obj 需要返回的对象
	 * @return result
	 */
	protected ResultBean renderSuccess(Object obj) {
		return new ResultBean(obj);
	}
}